<?php
namespace app\controller;

use app\BaseController;
use think\facade\Request;
use think\facade\Db;
use think\Exception;
use think\facade\Filesystem;
use think\facade\Log;
use think\Event;
use app\event\AssetHistoriesEvent;

class AssetUseBill extends BaseController
{
    //查询所有领用单及其明细
    public function getAllAssetUseBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        $current_page = Request::param('current_page');
        $page_size = Request::param('page_size');


        // 获取搜索表单参数
        $seachform = Request::param('seachform', [], 'trim'); // 使用trim过滤空白字符，并设置默认值为空数组

        // 初始化变量为null或默认值
        $begindate =$enddate=$billnumber=$state=$CustomerId=$branchId=null;
        //批量检查参数是否存在
        if (is_array($seachform)) {
            $begindate = $seachform['startDate'] ?? null;//开始日期购买日期
            $enddate = $seachform['endDate'] ?? null;//结束日期购买日期
            $billnumber = $seachform['BillNumber'] ?? null;//领用单号
            $state = $seachform['state'] ?? null;//领用单状态
            $CustomerId=$seachform['AssetUseBill_customer_id'] ?? null;
            $branchId=$seachform['AssetUseBill_branch_id'] ?? null;


        }

        // 构建查询条件
        $where = [];

        if ($begindate && $enddate) {
            // 设置开始日期的时分秒为00:00:00
            $startOfDay = date('Y-m-d 00:00:00', strtotime($begindate));
            // 设置结束日期的时分秒为23:59:59（或者你也可以选择结束日期的次日00:00:00来简化比较）
            $endOfDay = date('Y-m-d 23:59:59', strtotime($enddate));

            // 使用范围查询
            $where[] = ['AssetUseBill_creationtime', '>=', $startOfDay];
            $where[] = ['AssetUseBill_creationtime', '<=', $endOfDay];
        }

        if ($billnumber) {
            $where[] = ['AssetUseBill_BillNumber', 'like', '%' . $billnumber . '%'];

        }
        if ($branchId) {
            $where['AssetUseBill_branch_id'] = $branchId;
        }
        if ($companyId) {
            $where['AssetUseBill_company_id'] = $companyId;
        }
        if ($state) {
            $where['AssetUseBill_state'] = $state;
        }
        if($CustomerId){
            $where['AssetUseBill_customer_id'] = $CustomerId;
        }

        // 查询主表数据,按照PurchaseBill_creationtime时间字段排序
        $mainList = Db::table('vw_AssetUseBill')
            ->where($where)
            ->where('AssetUseBill_deleted', 0)
            ->order('AssetUseBill_creationtime', 'desc')//按时间降序排名
            ->page($current_page, $page_size)
            ->select()->toarray();


        foreach ($mainList as &$item) {
            // 查询对应的明细表数据
            $detailList = Db::table('vw_AssetUseBill_assets')
                ->where('AssetUseBill_id', $item['AssetUseBill_id'])
                ->select();

            // 将明细表数据附加到主表数据上
            $item['detail'] = $detailList;
        }

        unset($item); // 取消引用，避免后续对$item的修改影响到$mainList

        // 获取总记录数
        $totalCount = Db::table('vw_AssetUseBill')
            ->where($where)
            ->where('AssetUseBill_deleted', 0)
            ->order('AssetUseBill_creationtime', 'desc')//按时间降序排名
            ->count();

        // 返回JSON数据
        return json([
            'code' => 200, // 自定义状态码，0表示成功
            'msg' => '查询成功', // 自定义消息
            'data' => [
                'data' => $mainList, // 主表数组包含明细表数组
                'total' => $totalCount, // 总数量

            ]

        ]);



    }
    //添加领用单
    public function add_AssetUseBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        try {
            // 开启事务
            Db::startTrans();
            //生成领用单号
            $billnumber = generateOrderNumber($companyId,'LY','AssetUseBill');
            //获取主表的领用单信息和明细表信息
            $AssetUseBill = Request::param('AssetUseBill');
            $assets = filterEmptyValues(Request::param('assets'));
            //找查资产是否已经被其他未审核单据占用
            foreach ($assets as $asset){
                $findId=Db::table('AssetUseBill_assets')->where('assets_id',$asset['assets_id'])->value('AssetUseBill_id');
                if ($findId)
                {
                  $findAsset=Db::table('AssetUseBill')->where('AssetUseBill_id',$findId)->where('AssetUseBill_state','未审核')->value('AssetUseBill_BillNumber');
                  if($findAsset)
                  {
                      return json([
                          'code' => 201,
                          'msg' => '资产:'.$asset['assets_name'].' '.'编码:'.$asset['assets_code'].'已经被未审核领用单:'.$findAsset.'占用，请先处理此单据'
                      ]);
                  }

                }

            }



            $AssetUseBill['AssetUseBill_company_id'] = $companyId;
            $AssetUseBill['AssetUseBill_BillNumber'] = $billnumber;
            $AssetUseBill['AssetUseBill_state'] = '未审核';
            $AssetUseBill['AssetUseBill_quantity'] = count(Request::param('assets'));
            $AssetUseBill['AssetUseBill_user_id'] = $userId;

            $AssetUseBillId = Db::table('AssetUseBill')->insertGetId($AssetUseBill);

            if (!$AssetUseBillId) {
                throw new \Exception('添加领货单主记录失败');
            }

            // 遍历货品明细并添加记录
            foreach ($assets as $detail) {
                // 生成条码（这里假设有一个generateBarcode函数）
                //$barcode = generateBarcode($companyId);

                //$DetailBill = $detail;
                $DetailBill['AssetUseBill_id'] = $AssetUseBillId;
                //$DetailBill['AssetUseBill_company_id'] = $companyId;
                $DetailBill['assets_id'] = $detail['assets_id'];
                $DetailBill['before_department_id'] = $detail['assets_department_id'];
                $DetailBill['after_department_id'] = $AssetUseBill['AssetUseBill_department_id'];
                $DetailBill['before_location_id'] = $detail['assets_location_id'];
                $DetailBill['after_location_id'] = $AssetUseBill['AssetUseBill_location_id'];
                $DetailBill['before_branch_id']=$detail['assets_branch_id'];
                $DetailBill['after_branch_id']=$AssetUseBill['AssetUseBill_branch_id'];

                $result = Db::table('AssetUseBill_assets')->insert($DetailBill);
                if (!$result) {
                    throw new \Exception('添加领用单明细记录失败');
                }
            }

            // 提交事务
            Db::commit();

            // 添加成功，返回响应
            return json(['code' => '200', 'msg' => '领用单添加成功']);


        }catch (\Exception $e) {
            // 发生异常，回滚事务
            Db::rollback();

            // 返回错误信息
            return json(['code' => '402', 'msg' => $e->getMessage()]);


        }



    }

    //修改领用单主表
    public function update_AssetUseBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');


        try {

            Db::startTrans();
            $AssetUseBill_id = Request::param('AssetUseBill_id');
            $AssetUseBill = Request::param('data');
            if(empty($AssetUseBill)){
                throw new \Exception('修改数据不能为空');
            }else{
                $updateResult = Db::table('AssetUseBill')
                    ->where('AssetUseBill_id', $AssetUseBill_id)
                    ->update($AssetUseBill);

                //修改与之关联的AssetUseBill_assets表,只需要修改领用后的字段
                $result=Db::table('AssetUseBill_assets')
                    ->where('AssetUseBill_id',$AssetUseBill_id)
                    ->update([
                        'after_department_id'=>$AssetUseBill['AssetUseBill_department_id'],
                        'after_location_id'=>$AssetUseBill['AssetUseBill_location_id'],
                        'after_branch_id'=>$AssetUseBill['AssetUseBill_branch_id'],
                    ]);


                if (!$updateResult) {
                    throw new \Exception('更新领用单信息失败');
                }else{
                    Db::commit();
                    //返回更新成功信息
                    return json(['code' => 200,'msg' => '更新成功']);
                }
            }



        }catch (\Exception $e) {
            Db::rollback();
            return json(['code' => 500, 'msg' => $e->getMessage()]);
        }



    }


    //审核领用单
    public function check_AssetUseBill()
    {
        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        $AssetUseBill_id =Request::param('AssetUseBill_id');

        //审核前先查询资产的信息是否有改变，如果有则提示用户重新提单
        $AssetUseBill=Db::table('AssetUseBill_assets')->where('AssetUseBill_id',$AssetUseBill_id)->select();
        foreach ($AssetUseBill as $checkAssetItem){
            $Asset=Db::table('assets')->where('assets_id',$checkAssetItem['assets_id'])->find();
            if($Asset==null){
                return json(['code' => 201, 'msg' => '此单据有资产已被删除，请作废单据后重新提单']);
            }
            //将资产的信息与领用单的明细信息进行对比
            if($Asset['assets_status']!='闲置' || $Asset['assets_department_id']!=$checkAssetItem['before_department_id']||$Asset['assets_location_id']!=$checkAssetItem['before_location_id'] || $Asset['assets_InputStatus']!='已审核' || $Asset['assets_branch_id']!=$checkAssetItem['before_branch_id']){
                return json(['code' => 201, 'msg' => '资产:'.$Asset['assets_name'].' '.'编码:'.$Asset['assets_code'].'资产信息有改变，请作废单据后重新提单']);
            }
        }

        //审核领用单
        try {
            Db::startTrans();
            //直接审核领用单，更改领用单状态未已审核
            $updateResult = Db::table('AssetUseBill')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->update(['AssetUseBill_state' => '已审核']);

            $AssetUseBill_one=Db::table('AssetUseBill')->where('AssetUseBill_id',$AssetUseBill_id)->value('AssetUseBill_customer_id');


            // 首先，获取AssetUseBill_assets表中需要的所有信息
            $assetUseBillAssets = Db::table('AssetUseBill_assets')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->select();

             // 准备用于更新的数据
            $updateData = [];

            //构造修改资产的数据集
            foreach ($assetUseBillAssets as $asset) {
                $state='';
                if($AssetUseBill_one){
                    $state='在用';
                }else{
                    $state='在用/公共';

                }
                $updateData[] = [
                    'assets_id' => $asset['assets_id'],
                    'assets_status' => $state,
                    'assets_department_id' => $asset['after_department_id'], // 假设这些字段存在
                    'assets_location_id' => $asset['after_location_id'],
                    'assets_customer_id'=>$AssetUseBill_one,
                    'assets_branch_id'=>$asset['after_branch_id']
                ];
            }

            //修改资产状态
            foreach ($updateData as $data) {
                Db::table('assets')
                    ->where('assets_id', $data['assets_id'])
                    ->update([
                        'assets_status' => $data['assets_status'],
                        'assets_department_id' => $data['assets_department_id'],
                        'assets_location_id' => $data['assets_location_id'],
                        'assets_customer_id'=>$data['assets_customer_id'],
                        'assets_branch_id'=>$data['assets_branch_id']
                    ]);
            }

            //使用事件触发器
            event(new AssetHistoriesEvent($AssetUseBill_id, $updateData, $userId, $companyId,'领用'));


            //直接返回json结果
            if (!$updateResult) {
                Db::rollback();
                throw new \Exception('审核领用单失败');
            }else{
                Db::commit();
                //返回审核成功信息
                return json(['code' => 200,'msg' => '审核成功']);
            }

        }
        catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }


    }

    //作废领用单
    public function invalid_AssetUseBill()
    {

        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');
        try {
            Db::startTrans();
            $AssetUseBill_id =Request::param('AssetUseBill_id');
            //作废领用单
            $updateResult = Db::table('AssetUseBill')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->update(['AssetUseBill_state' => '已作废']);
            //直接返回json结果
            if (!$updateResult) {
                Db::rollback();
                throw new \Exception('作废领用单失败');
            }else{
                Db::commit();
                //返回作废成功信息
                return json(['code' => 200,'msg' => '作废成功']);
            }

        }
        catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }


    }

    //删除领用单
    public function delete_AssetUseBill()
    {
        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');

        try {
            Db::startTrans();
            $AssetUseBill_id =Request::param('AssetUseBill_id');
            //删除领用单
            $updateResult = Db::table('AssetUseBill')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->delete();
            $deleteResult = Db::table('AssetUseBill_assets')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->delete();
            //直接返回json结果
            if (!$updateResult || !$deleteResult) {
                Db::rollback();
                throw new \Exception('删除领用单失败');
            }else{
                Db::commit();
                //返回删除成功信息
                return json(['code' => 200,'msg' => '删除成功']);
            }

        }
        catch (\Exception$e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }


    }

    //反审核领用单
    public function uncheck_AssetUseBill()
    {
        $userRoot = $this->request->auth['data']->user->user_root;
        $userId = $this->request->auth['data']->user->user_id;


        // 根据用户ID获取公司ID
        $companyId = Db::name('user')->where('user_id', $userId)->value('user_company_id');
        try {
            Db::startTrans();
            $AssetUseBill_id =Request::param('AssetUseBill_id');
            //先检查领用单状态
            $AssetUseBill_one = Db::table('AssetUseBill')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->find();
            //根据领用单id找查AssetUseBill_assets表中对应的所有资产id，再根据这些资产id在AssetHistories表中找对应的历史记录,再根据资产的历史记录一条一条比对，首先找到AssetHistories_bill_id字段对应$AssetUseBill_id的记录，以这条记录AssetHistories_date字段为标准，如果资产有其他记录的时间大于这条记录的时间，则不能反审核，否则可以反审核
            $AssetUseBill_assets = Db::table('AssetUseBill_assets')
                ->where('AssetUseBill_id', $AssetUseBill_id)
                ->select()->toArray();
            $AssetUseBill_assets_id = array_column($AssetUseBill_assets, 'assets_id');
            $AssetHistories_date = Db::table('AssetHistories')
                ->where('AssetHistories_bill_id', $AssetUseBill_id)
                ->where('AssetHistories_assets_id', 'in', $AssetUseBill_assets_id)
                ->where('AssetHistories_type','领用')
                ->order('AssetHistories_date', 'desc')
                ->value('AssetHistories_date');
            if ($AssetUseBill_one['AssetUseBill_state'] == '已审核') {
                $AssetHistories_date_one = Db::table('AssetHistories')
                    ->where('AssetHistories_bill_id', '<>', $AssetUseBill_id)
                    ->where('AssetHistories_assets_id', 'in', $AssetUseBill_assets_id)
                    ->where('AssetHistories_date', '>', $AssetHistories_date)
                    ->find();
                if ($AssetHistories_date_one) {
                    //json返回是哪个资产,拼接返回显示资产编号资产名称
                    $Asset_one = Db::table('assets')
                        ->where('assets_id', $AssetHistories_date_one['AssetHistories_assets_id'])
                        ->find();
                    $Asset_name = $Asset_one['assets_name'];
                    $Asset_number = $Asset_one['assets_code'];
                    return json([
                        'code' => 500,
                        'msg' => '资产:'.$Asset_name.' 编号:'.$Asset_number.' 已产生了'.$AssetHistories_date_one['AssetHistories_type'].'单据,单据号:'.getBillNumber($AssetHistories_date_one['AssetHistories_type'],$AssetHistories_date_one['AssetHistories_bill_id']).'请先处理此单据',
                        'data' => [
                            'Asset_name' => $Asset_name,
                            'Asset_number' => $Asset_number
                        ]
                    ]);
                    throw new \Exception('该资产有历史记录，不能反审核');
                }else{
                    //反审核领用单
                    $updateResult = Db::table('AssetUseBill')
                        ->where('AssetUseBill_id', $AssetUseBill_id)
                        ->update(['AssetUseBill_state' => '未审核']);
                    //修改回该领用单对应的资产的所有资产信息，根据AssetUseBill_assets表中before_department_id和before_location_id字段修改
                    $AssetUseBill_assets_one = Db::table('AssetUseBill_assets')
                        ->where('AssetUseBill_id', $AssetUseBill_id)
                        ->select()->toArray();
                    for ($i = 0; $i < count($AssetUseBill_assets_one); $i++) {
                        $Asset_id = $AssetUseBill_assets_one[$i]['assets_id'];
                        $Asset_before_department_id = $AssetUseBill_assets_one[$i]['before_department_id'];
                        $Asset_before_location_id = $AssetUseBill_assets_one[$i]['before_location_id'];
                        $Asset_before_branch_id=$AssetUseBill_assets_one[$i]['before_branch_id'];


                        $updateResult = Db::table('assets')
                            ->where('assets_id', $Asset_id)
                            ->update(['assets_department_id' => $Asset_before_department_id, 'assets_location_id' => $Asset_before_location_id,'assets_customer_id'=>null,'assets_status'=>'闲置','assets_branch_id'=>$Asset_before_branch_id]);
                        //删除对应的历史记录
                        $deleteResult = Db::table('AssetHistories')
                            ->where('AssetHistories_bill_id', $AssetUseBill_id)
                            ->where('AssetHistories_assets_id', $Asset_id)
                            ->where('AssetHistories_type','领用')
                            ->delete();
                        if (!$updateResult || !$deleteResult) {
                            Db::rollback();
                            throw new \Exception('反审核失败');
                        }
                    }

                    //直接返回json结果
                    if (!$updateResult) {
                       Db::rollback();
                   }
                    Db::commit();
                    return json(['code' => 200,'msg' => '反审核成功']);
               }


            }


        }
        catch (\Exception $e) {
            Db::rollback();
            return json([
                'code' => 500,
                'msg' => $e->getMessage()
            ]);
        }





    }



}






